package com.fz.song.feibao.web.controller.member;


import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.fz.song.feibao.framework.common.R;
import com.fz.song.feibao.framework.common.RedisKey;
import com.fz.song.feibao.framework.common.enums.CodeEnum;
import com.fz.song.feibao.framework.common.enums.MemberStateEnum;
import com.fz.song.feibao.framework.common.util.StpMemberUtil;
import com.fz.song.feibao.framework.exceptions.ServerException;
import com.fz.song.feibao.web.entity.Member;
import com.fz.song.feibao.web.entity.vo.login.req.MemberLoginReqVO;
import com.fz.song.feibao.web.entity.vo.register.req.MemberRegisterReqVO;
import com.fz.song.feibao.web.entity.vo.register.req.VerifyCodeReqVO;
import com.fz.song.feibao.web.service.IMemberService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.validator.constraints.Length;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;


@Api(tags = "会员登录-登出控制器")
@Slf4j
@RestController
@RequestMapping("member")
public class MemberLoginController {


    @Value("${feibao.member.user-key}")
    private String userKey;

    @Autowired
    private IMemberService memberService;

    @Autowired
    private StringRedisTemplate redisTemplate;


    @ApiOperation("会员登录系统")
    @PostMapping("login")
    public R login(@Valid @RequestBody MemberLoginReqVO req) {
        log.debug("会员登录系统:{}", JSONUtil.toJsonStr(req));

        Member member = memberService.queryMemberUserName(req.getUsername());
        if (member == null) {
            throw new ServerException(CodeEnum.USERNAME_OR_PWD_ERROR);
        }
        if (member.getState() == MemberStateEnum.LOCK.getVal()) {
            throw new ServerException(CodeEnum.USER_IS_LOCK);
        }
        Integer id = member.getId();
        String pwd = member.getPassword();
        String password = req.getPassword();
        String pwdEn = SaSecureUtil.md5BySalt(password, userKey);
        if (!pwdEn.equals(pwd)) {
            throw new ServerException(CodeEnum.USERNAME_OR_PWD_ERROR);
        }
        StpMemberUtil.login(id);
        SaTokenInfo token = StpMemberUtil.getTokenInfo();
        HashMap<String, Object> map = new HashMap<>();
        map.put("tokenName", token.getTokenName());
        map.put("tokenValue", token.getTokenValue());
        map.put("token", token);
        return R.ok("登录成功", map);
    }

    @ApiOperation("会员退出系统")
    @GetMapping("logout")
    @SaCheckLogin(type = StpMemberUtil.TYPE)
    public R logout() {
        StpMemberUtil.logout();
        return R.ok("退出成功");
    }


    @ApiOperation("获取短信验证码")
    @PostMapping("verifyCode")
    public R register(@Valid @RequestBody VerifyCodeReqVO req) {
        log.debug("获取短信验证码:{}", JSONUtil.toJsonStr(req));
        String mobile = req.getMobile();
        String key = RedisKey.VERIFY_CODE + mobile;
        String val = redisTemplate.opsForValue().get(key);
        if (StrUtil.isNotBlank(val)) {
            throw new ServerException(CodeEnum.GET_VERIFY_CODE_TOO_MUCH);
        }
        String numbers = RandomUtil.randomNumbers(4);
        redisTemplate.opsForValue().set(key, numbers, 5, TimeUnit.MINUTES);
        return R.ok("获取短信验证码", numbers);
    }

    @ApiOperation("会员注册系统")
    @PostMapping("register")
    public R register(@Valid @RequestBody MemberRegisterReqVO req) {
        log.debug("会员注册系统:{}", JSONUtil.toJsonStr(req));
        Boolean bool = memberService.register(req);
        return R.ok("用户注册", bool);
    }

    @ApiOperation("检查用户名是否存在")
    @GetMapping("userNameIsExist")
    public R userNameIsExist(@Valid @RequestBody String userName) {
        log.debug("检查用户名是否存在:{}", userName);
        Boolean bool = memberService.userNameIsExist(userName);
        return R.ok("检查用户名是否存在", bool);
    }

    @ApiOperation("检查手机号是否存在")
    @GetMapping("mobileIsExist")
    public R mobileIsExist(@Valid @RequestBody String mobile) {
        log.debug("检查手机号是否存在:{}", mobile);
        Boolean bool = memberService.mobileIsExist(mobile);
        return R.ok("检查手机号是否存在", bool);
    }

    @ApiOperation("检查昵称是否存在")
    @GetMapping("nicknameIsExist")
    public R nicknameIsExist(@Valid @RequestBody String nickname) {
        log.debug("检查昵称是否存在:{}", nickname);
        Boolean bool = memberService.nicknameIsExist(nickname);
        return R.ok("检查昵称是否存在", bool);
    }
}
